/**   
 *  This file is part of WaterfallDisplay.

 *  WaterfallDisplay is free software: you can redistribute it and/or modify   
 *  it under the terms of the GNU General Public License as published by   
 *  the Free Software Foundation, either version 3 of the License, or   
 *  (at your option) any later version.

 *  WaterfallDisplay is distributed in the hope that it will be useful,   
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of   
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   
 *  GNU General Public License for more details.

 *  See <http://www.gnu.org/licenses/>.

 */  
package waterfall.demo;

import java.text.DecimalFormat;
import java.text.NumberFormat;

import waterfall.Waterfall;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.Property;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.LabelBuilder;
import javafx.scene.control.Slider;
import javafx.scene.control.SliderBuilder;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Text;
import javafx.scene.text.TextBuilder;

/**
 * @author altug.uzunali
 *
 */
public class PropertyPane extends GridPane {
	private static final NumberFormat twoDp = new DecimalFormat("0.##");
	private static final NumberFormat zeroDp = new DecimalFormat("0");
	private static final Color foregroundColor = Color.WHITE;
	
	public PropertyPane(final Waterfall waterfall) {
		setHgap(10);
		setVgap(10);

		Label title = LabelBuilder.create()
    			.text("Play with these:")
    			.textFill(foregroundColor).build();
		GridPane.setConstraints(title, 0, 0);
		getChildren().add(title);

		createColorPickerRow(waterfall.firstColorProperty(), "Waterfall first color: ", 1);
		createSliderRow(waterfall.firstLimitProperty(), "Waterfall first color limit: ", 2, 128, 2);
		createColorPickerRow(waterfall.secondColorProperty(), "Waterfall second color: ", 3);
		createSliderRow(waterfall.secondLimitProperty(), "Waterfall second color limit: ", 2, 128, 4);
		createColorPickerRow(waterfall.overlayColorProperty(), "Overlay text color: ", 5);
		createColorPickerRow(waterfall.intervalLineColorProperty(), "Interval change line color: ", 6);
		createColorPickerRow(waterfall.crosshairsColorProperty(), "Cross hairs line color: ", 7);
		createSliderRow(waterfall.crosshairsDashedProperty(), "Cross hairs dash value: ", 0.0, 10.0, 8);
		createSliderRow(waterfall.refreshIntervalProperty(), "Refresh interval time: ", 200, 3200, 9);
		createTextFieldRow(waterfall.intensityProperty(), "Intensity: ", 10);
	}
	
    private static String formatWebColor(Color c) {
        String r = Integer.toHexString((int)(c.getRed() * 255));
        if (r.length() == 1) r = "0" + r;
        String g = Integer.toHexString((int)(c.getGreen() * 255));
        if (g.length() == 1) g = "0" + g;
        String b = Integer.toHexString((int)(c.getBlue() * 255));
        if (b.length() == 1) b = "0" + b;
        return "#" + r + g + b;
    }
    
    private void createSliderRow(final Property<Number> property, String title, Number min, Number max, int row) {
    	Label titleLabel = LabelBuilder.create()
    			.text(title)
    			.textFill(foregroundColor).build();
        GridPane.setConstraints(titleLabel, 0, row);
    	
        final Label valueLabel = LabelBuilder.create()
    			.text(zeroDp.format(property.getValue()))
    			.textFill(foregroundColor)
    			.build();
        GridPane.setConstraints(valueLabel, 2, row);
        
        final Slider slider = SliderBuilder.create()
        		.min(min.doubleValue())
        		.max(max.doubleValue())
        		.value(property.getValue().doubleValue())
        		.maxWidth(Double.MAX_VALUE).build();
        GridPane.setConstraints(slider, 1, row);

        slider.valueProperty().addListener(new InvalidationListener() {
            @Override public void invalidated(Observable ov) {
                property.setValue(slider.getValue());
                if (property.getValue() instanceof Integer)
                	valueLabel.setText(zeroDp.format(slider.getValue()));
                else 
                	valueLabel.setText(twoDp.format(slider.getValue()));
            }
        });
        getChildren().addAll(titleLabel, slider, valueLabel);
    }
    
    private void createColorPickerRow(Property<Color> colorProperty, String title, int row) {
    	Label titleLabel = LabelBuilder.create()
    			.text(title)
    			.textFill(foregroundColor).build();
		GridPane.setConstraints(titleLabel, 0, row);
		getChildren().add(titleLabel);
		
		Rectangle colorRectangle = createColorRectangle(colorProperty);
		Label colorLabel = createColorLabel(colorProperty, colorRectangle);
		SimpleHSBColorPicker colorPicker = createColorPicker(colorProperty, colorRectangle, colorLabel);
		GridPane.setConstraints(colorPicker, 1, row);
		getChildren().add(colorPicker);
        GridPane.setConstraints(colorLabel, 2, row);
        getChildren().add(colorLabel);
    }
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
	private void createTextFieldRow(Property<Number> property, String title, int row) {
    	Label titleLabel = LabelBuilder.create()
    			.text(title)
    			.textFill(foregroundColor).build();
		GridPane.setConstraints(titleLabel, 0, row);
		getChildren().add(titleLabel);
		
		final Text text = TextBuilder.create()
				.text(String.valueOf(property.getValue()))
				.fill(foregroundColor).build();
		property.addListener(new ChangeListener() {

			@Override
			public void changed(ObservableValue arg0, Object arg1, Object arg2) {
				text.setText(String.valueOf(arg2));
			}
		});
		GridPane.setConstraints(text, 1, row);
		getChildren().add(text);
    }
    
    private Rectangle createColorRectangle(Property<Color> colorProperty) {
    	final Rectangle colorRect = new Rectangle(20,20, (Color)colorProperty.getValue());
        colorRect.setStroke(Color.GRAY);
        
        return colorRect;
    }
    
    private Label createColorLabel(Property<Color> colorProperty, Rectangle colorRectangle) {
    	final Label colorLabel = LabelBuilder.create()
    			.text(formatWebColor((Color)colorProperty.getValue()))
    			.graphic(colorRectangle)
    			.contentDisplay(ContentDisplay.LEFT)
    			.textFill(foregroundColor).build();
         
         return colorLabel;
    }
    
    private SimpleHSBColorPicker createColorPicker(final Property<Color> colorProperty, final Rectangle colorRectangle, final Label colorLabel) {
    	final SimpleHSBColorPicker picker = new SimpleHSBColorPicker();
    	picker.getColor().addListener(new InvalidationListener() {
			@Override
			public void invalidated(Observable arg0) {
				Color c = picker.getColor().get();
				colorProperty.setValue(c);
				colorLabel.setText(formatWebColor(c));
                colorRectangle.setFill(c);
			}
		});
    	
		return picker;
    }
}
